From 51620845044bc2a79a36ee2ca62e111345cf31ab Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 7 Nov 2003 16:37:15 +0000 Subject: [PATCH] bitkeeper revision 1.572 (3fabca3boPogE8eX_8H6P5qlR4SCEQ) memory.c, xi_save_linux.c, xi_restore_linux.c: Moire fixes. Save/restore now works. --- tools/internal/xi_restore_linux.c | 39 ++++++++++++++++++++++++++----- tools/internal/xi_save_linux.c | 20 ++++++++++++++++ xen/common/memory.c | 20 ++++++++++++---- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/tools/internal/xi_restore_linux.c b/tools/internal/xi_restore_linux.c index bd42e62952..8ccd145d93 100644 --- a/tools/internal/xi_restore_linux.c +++ b/tools/internal/xi_restore_linux.c @@ -15,6 +15,13 @@ static char *argv0 = "internal_restore_linux"; /* A table mapping each PFN to its new MFN. */ static unsigned long *pfn_to_mfn_table; +/* This may allow us to create a 'quiet' command-line option, if necessary. */ +#define verbose_printf(_f, _a...) \ + do { \ + printf( _f , ## _a ); \ + fflush(stdout); \ + } while ( 0 ) + static int get_pfn_list( int domain_id, unsigned long *pfn_buf, unsigned long max_pfns) { @@ -126,6 +133,7 @@ int main(int argc, char **argv) dom0_op_t op; int rc = 1, i, j; unsigned long mfn, pfn, dom = 0; + unsigned int prev_pc, this_pc; /* Number of page frames in use by this XenoLinux session. */ unsigned long nr_pfns; @@ -256,12 +264,22 @@ int main(int argc, char **argv) goto out; } + verbose_printf("Reloading memory pages: 0%%"); + /* * Now simply read each saved frame into its new machine frame. * We uncanonicalise page tables as we go. */ + prev_pc = 0; for ( i = 0; i < nr_pfns; i++ ) { + this_pc = (i * 100) / nr_pfns; + if ( (this_pc - prev_pc) >= 5 ) + { + verbose_printf("\b\b\b\b%3d%%", this_pc); + prev_pc = this_pc; + } + mfn = pfn_to_mfn_table[i]; if ( !checked_read(fd, page, PAGE_SIZE) ) @@ -348,6 +366,8 @@ int main(int argc, char **argv) if ( flush_mmu_updates() ) goto out; + verbose_printf("\b\b\b\b100%%\nMemory reloaded.\n"); + /* Uncanonicalise the suspend-record frame number and poke resume rec. */ pfn = ctxt.i386_ctxt.esi; if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NONE) ) @@ -446,13 +466,20 @@ int main(int argc, char **argv) rc = do_dom0_op(&op); out: - /* If we experience an error then kill the half-constructed domain. */ - if ( (rc != 0) && (dom != 0) ) + if ( rc != 0 ) + { + if ( dom != 0 ) + { + op.cmd = DOM0_DESTROYDOMAIN; + op.u.destroydomain.domain = dom; + op.u.destroydomain.force = 1; + (void)do_dom0_op(&op); + } + } + else { - op.cmd = DOM0_DESTROYDOMAIN; - op.u.destroydomain.domain = dom; - op.u.destroydomain.force = 1; - (void)do_dom0_op(&op); + /* Success: print the domain id. */ + printf("DOM=%ld\n", dom); } return !!rc; diff --git a/tools/internal/xi_save_linux.c b/tools/internal/xi_save_linux.c index 54d0a40550..bbefaa1fb3 100644 --- a/tools/internal/xi_save_linux.c +++ b/tools/internal/xi_save_linux.c @@ -17,6 +17,13 @@ static unsigned long *pfn_to_mfn_table; /* A table mapping each current MFN to its canonical PFN. */ static unsigned long *mfn_to_pfn_table; +/* This may allow us to create a 'quiet' command-line option, if necessary. */ +#define verbose_printf(_f, _a...) \ + do { \ + printf( _f , ## _a ); \ + fflush(stdout); \ + } while ( 0 ) + static int devmem_fd; static int init_pfn_mapper(void) @@ -100,6 +107,7 @@ int main(int argc, char **argv) dom0_op_t op; int rc = 1, i, j; unsigned long mfn, dom; + unsigned int prev_pc, this_pc; /* Remember if we stopped the guest, so we can restart it on exit. */ int we_stopped_it = 0; @@ -319,9 +327,19 @@ int main(int argc, char **argv) } unmap_pfn(ppage); + verbose_printf("Saving memory pages: 0%%"); + /* Now write out each data page, canonicalising page tables as we go... */ + prev_pc = 0; for ( i = 0; i < srec.nr_pfns; i++ ) { + this_pc = (i * 100) / srec.nr_pfns; + if ( (this_pc - prev_pc) >= 5 ) + { + verbose_printf("\b\b\b\b%3d%%", this_pc); + prev_pc = this_pc; + } + mfn = pfn_to_mfn_table[i]; ppage = map_pfn(mfn); @@ -354,6 +372,8 @@ int main(int argc, char **argv) } } + verbose_printf("\b\b\b\b100%%\nMemory saved.\n"); + /* Success! */ rc = 0; diff --git a/xen/common/memory.c b/xen/common/memory.c index 0eb478c6ee..c2349d3240 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -138,7 +138,7 @@ #include #include -#if 1 +#if 0 #define MEM_LOG(_f, _a...) printk("DOM%d: (file=memory.c, line=%d) " _f "\n", current->domain, __LINE__, ## _a ) #else #define MEM_LOG(_f, _a...) ((void)0) @@ -395,6 +395,8 @@ static int get_twisted_l2_table(unsigned long entry_pfn, l2_pgentry_t l2e) static int get_l2_table(unsigned long page_nr) { + struct pfn_info *page; + struct task_struct *p; l2_pgentry_t *p_l2_entry, l2_entry; int i, ret=0; @@ -424,13 +426,23 @@ static int get_l2_table(unsigned long page_nr) memcpy(p_l2_entry, &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE], HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t)); - p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) - - DOMAIN_ENTRIES_PER_L2_PAGETABLE] = - mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR); p_l2_entry[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT) - DOMAIN_ENTRIES_PER_L2_PAGETABLE] = mk_l2_pgentry((page_nr << PAGE_SHIFT) | __PAGE_HYPERVISOR); + /* + * The per-domain PGD is slightly tricky, as we may not be executing + * in the context of the correct domain (DOM0 builds pt's for others). + */ + page = frame_table + page_nr; + if ( (p = find_domain_by_id(page->flags & PG_domain_mask)) != NULL ) + { + p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) - + DOMAIN_ENTRIES_PER_L2_PAGETABLE] = + mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR); + put_task_struct(p); + } + out: unmap_domain_mem(p_l2_entry); return ret; -- 2.30.2